package com.juku2024.juku

import android.content.Intent
import android.os.Bundle
import android.text.Spannable
import android.text.SpannableString
import android.text.TextUtils
import android.text.style.ForegroundColorSpan
import android.view.View
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.Group
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.blankj.utilcode.util.ConvertUtils
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.listener.OnItemClickListener
import com.juku2024.juku.adapter.DownloadListAdapter
import com.juku2024.juku.adapter.DownloadSourceAdapter
import com.juku2024.juku.analysis.AnalysisVideoTools
import com.juku2024.juku.analysis.OnParseVideoListener
import com.juku2024.juku.base.BaseActivity
import com.juku2024.juku.callback.OnNoDoubleClickListener
import com.juku2024.juku.db.NoteRoomUtils
import com.juku2024.juku.db.entity.VideoEntity
import com.juku2024.juku.dialog.DialogUtils
import com.juku2024.juku.dialog.DownloadRewardAdDialog
import com.juku2024.juku.dialog.SourceSelectDialog
import com.juku2024.juku.model.PlayInfoResponse
import com.juku2024.juku.model.VideoSourceModel
import com.juku2024.juku.network.retrofit.OnRetrofitResultListener
import com.juku2024.juku.tools.*
import com.juku2024.juku.viewmodel.VideoDetailViewModelNew
import com.juku2024.juku.widget.LoadingView
import com.wanban.download.WBDownloadUtils
import com.wanban.download.db.DownloadEntity
import com.wanban.download.model.Status
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode


class VideoDownloadActivity : BaseActivity(), OnNoDoubleClickListener {

    private lateinit var btnChangeSource: View
    private lateinit var btn2Download: View
    private lateinit var tvSourceName: TextView
    private lateinit var tvDownloadCount: TextView
    private lateinit var tvFreeStoreSize: TextView
    private lateinit var downloadRecycler: RecyclerView
    private lateinit var loadingView: LoadingView
    private lateinit var groupTvList: Group
    private lateinit var layoutLoading: ConstraintLayout
    private lateinit var downloadSourceRecycler: RecyclerView

    private var videoId = -1L
    // 当前的视频id，如果相同的视频，不再充值adapter
    private var sourceId = -1
    private var videoPic = ""
    private var videoName = ""
    private var category = Constants.VIDEO_CATEGORY_ALBUM
    // 剩余存储空间大小
    private var freeStoreSize = 0L
    // 下载的线路
    private var downloadSource: PlayInfoResponse? = null
    private var videoDownloadAdDialog: DownloadRewardAdDialog? = null
    // 降序排序后的线路集合
    private val newPlayInfoList = ArrayList<PlayInfoResponse>()
    // 当前显示的剧集列表
    private val downloadAdapter by lazy { DownloadListAdapter(ArrayList()) }
    // 当前所有的线路列表
    private val downloadSourceAdapter by lazy { DownloadSourceAdapter(ArrayList()) }

    // 数据控制器
    private val viewModel by lazy { getViewModel(VideoDetailViewModelNew::class.java) }


    override fun getLayoutResId(): Int {
        return R.layout.activity_video_download
    }

    override fun initView() {
        super.initView()
        btnChangeSource = findViewById(R.id.layout_download_dialog_change_source)
        btn2Download = findViewById(R.id.linearToDownload)
        tvSourceName = findViewById(R.id.tvVideoQualityTitle)
        tvDownloadCount = findViewById(R.id.tvSelectCount)
        tvFreeStoreSize = findViewById(R.id.tvRomSize)
        layoutLoading = findViewById(R.id.layout_loading_view)
        downloadRecycler = findViewById(R.id.dialog_download_recycler)
        loadingView = findViewById(R.id.download_dialog_loadingView)
        downloadSourceRecycler = findViewById(R.id.download_dialog_source_recycler)
        groupTvList = findViewById(R.id.group_tv_list)

        downloadRecycler.adapter = downloadAdapter
        downloadSourceRecycler.layoutManager = WrapLinearLayoutManager(this, RecyclerView.HORIZONTAL)
        downloadSourceRecycler.adapter = downloadSourceAdapter
        loadingView.showLoading()
    }

    override fun bindEvent() {
        super.bindEvent()
        btn2Download.setOnClickListener {
            val intent = Intent(this@VideoDownloadActivity, DownloadDetailActivity::class.java)
            intent.putExtra("action", true)
            startActivity(intent)
        }
        downloadAdapter.setOnItemClickListener { _, _, position ->
            execDownload(position)
        }


        downloadSourceAdapter.setOnItemClickListener { _, _, position ->
            val item = downloadSourceAdapter.getItem(position)
            if (item.isSelected) return@setOnItemClickListener
            val index = downloadSourceAdapter.data.indexOfFirst { it.isSelected }
            if (index < 0) {
                downloadSourceAdapter.data.forEach {
                    it.isSelected = false
                }
                downloadSourceAdapter.setList(downloadSourceAdapter.data)
            } else {
                downloadSourceAdapter.getItem(index).isSelected = false
                downloadSourceAdapter.notifyItemChanged(index)
            }

            item.isSelected = true
            downloadSourceAdapter.notifyItemChanged(position)
            downloadSource = item
            // 切源
            // 修改当前下载源的名字
            tvSourceName.text = AppUtils.getSourceName(downloadSource?.id ?: 0)
            // 修改剧集列表
            downloadAdapter.setList(downloadSource?.episodes)
        }
    }

    override fun init(savedInstanceState: Bundle?) {
        videoId = intent?.getLongExtra(Constants.AROUTER_KEY_VIDEO_ID, -1L)?:-1L
        sourceId = intent?.getIntExtra(Constants.INTENT_KEY_VIDEO_SOURCE_ID, 0)?:0
        if (videoId <= 0) {
            loadingView.hideLoading()
            loadingView.showErrorStatus("当前视频信息获取失败！", getString(R.string.back)) {
                finish()
            }
            return
        }

        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this)
        }

        freeStoreSize = if (WBDownloadUtils.isUseSdcardDownload()) {
            AppUtils.getAvailableSdcardMemorySize()
        } else {
            AppUtils.getAvailableInternalMemorySize()
        }

        // 设置空余空间大小
        setFreeStoreSize()
        // 正在下载个数
        setCurrentRunningTaskCount()

        viewModel.hasDownloadAd { isAllowShowAd ->
            if (isAllowShowAd) {
                showDownloadAdDialog()
            }
            doGetVideoDetail(videoId)
        }
    }

    private fun doGetVideoDetail(videoId: Long){
        viewModel.getVideoDetail(videoId, object: OnRetrofitResultListener<VideoEntity>{
            override fun onSuccess(t: VideoEntity) {
                if (isActivityNotActive()) return
                loadingView.hideLoading()
                if (t.sourcePlayList.isNullOrEmpty()) {
                    showErrorDialog("没有找到可下载的视频!", getString(R.string.back), yesClickListener = {
                        finish()
                    })
                    return
                }
                groupTvList.visibility = View.VISIBLE
                videoPic = t.pic?:""
                videoName = t.name?:""
                category = t.category
                // 初始化顶部线路列表
                // 获取当前所有线路中正在下载的视频个数
                newPlayInfoList.clear()
                newPlayInfoList.addAll(t.sourcePlayList!!.filter { it.id < 21 || it.id > 28 })
                newPlayInfoList.forEachIndexed { position, source ->
                    // 找到当前应该被选中的线路
                    source.isSelected = if (sourceId == -1) {
                        position == 0
                    } else {
                        source.id == sourceId
                    }
                }

                if (newPlayInfoList.all { !it.isSelected }) { // 没有选中的线路
                    // 强制设置第一个选中
                    newPlayInfoList.firstOrNull()?.isSelected = true
                }

                downloadSource = newPlayInfoList.firstOrNull { it.isSelected }
                // 修改当前下载源的名字
                tvSourceName.text = AppUtils.getSourceName(downloadSource?.id?:0)
                // 设置线路列表
                downloadSourceAdapter.setList(newPlayInfoList)
                // 如果当前线路不在页面显示中，滚动列表，让选中的item出现在屏幕
                val layoutManager = downloadSourceRecycler.layoutManager as LinearLayoutManager
                var index = downloadSourceAdapter.data.indexOfFirst { it.isSelected }
                if (index < 0) {
                    index = 0
                }
                if (index < layoutManager.findFirstVisibleItemPosition() || index > layoutManager.findLastVisibleItemPosition()) {
                    downloadSourceRecycler.post {
                        downloadSourceRecycler.scrollToPosition(index)
                    }
                }

                // 初始化选中线路的剧集列表
                downloadAdapter.isAlbumType = category == Constants.VIDEO_CATEGORY_ALBUM

                val span = if (downloadAdapter.isAlbumType) 5 else 2
                downloadRecycler.layoutManager = WrapGridLayoutManager(this@VideoDownloadActivity, span)
                downloadAdapter.setList(downloadSource?.episodes)
            }

            override fun onFailed(msg: String) {
                if (isActivityNotActive()) return
                loadingView.hideLoading()
                loadingView.showErrorStatus(msg, getString(R.string.retry)) {
                    loadingView.showLoading()
                    loadingView.postDelayed({
                        doGetVideoDetail(videoId)
                    }, 1000)
                }
            }

        })

    }


    // 下载广告提示弹窗
    private fun showDownloadAdDialog() {
        if (videoDownloadAdDialog == null) {
            videoDownloadAdDialog = DownloadRewardAdDialog(this)
            videoDownloadAdDialog?.onShowAdListener = object: OnNoDoubleClickListener {
                override fun onNoDoubleClick(v: View?) {
                    super.onNoDoubleClick(v)
                    viewModel.loadMultipleAd(this@VideoDownloadActivity,
                        VideoDetailViewModelNew.AD_TYPE_DOWNLOAD
                    ) {
                        videoDownloadAdDialog?.dismiss()
                    }
                }
            }
        }
        videoDownloadAdDialog?.show()
    }



    // 设置剩余空间
    private fun setFreeStoreSize(fileSize: Long = 0L) {
        freeStoreSize -= fileSize
        if (freeStoreSize <= 1024 * 500) {
            AlertUtils.alert("当前存储空间不足，无法下载！")
            return
        }
        tvFreeStoreSize.text = String.format(AppUtils.getString(R.string.tv_left_size), ConvertUtils.byte2FitMemorySize(freeStoreSize, 2))
    }

    // 正在下载个数
    private fun setCurrentRunningTaskCount(){
//        val downloadingCount = MultiDownloadManager.getCanStartTasks().size
        val downloadingCount = WBDownloadUtils.getCanRunningTasks().size
        tvDownloadCount.text = downloadingCount.toString()
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onDownloadEvent(event: DownloadEntity) {
        setCurrentRunningTaskCount()
        // 非当前视频不处理
        if (event.videoId != videoId) return

        // 更新newPlayInfoList
        val sourceData = newPlayInfoList.firstOrNull { it.id == event.sourceId }?:return
        val episodeData = sourceData.episodes?.getOrNull(event.episode)?:return
        // 相同状态就不在处理
        if (event.state == Status.DOWNLOADING && episodeData.status == event.state) return

//        Log.d(MultiDownloadManager.TAG, "==========${event.getFileName()} -> 接收到下载更新==========")
        // 更新剧集列表中item下载状态
        episodeData.status = event.state
        episodeData.isDownloading = event.state != Status.IDLE && event.state != Status.DELETE
        if (event.sourceId == downloadSource?.id) { // 如果当前下载的视频在显示的剧集列表中，需要更新状态
            downloadAdapter.notifyItemChanged(event.episode)
        }

        // 更新线路列表状态
        // 找到下载视频的线路index
        val sourceIndex = downloadSourceAdapter.data.indexOfFirst { it.id == event.sourceId }
        if (sourceIndex < 0) return
        // 找到对应下载线路对象
        val hasDownloadTip = sourceData.episodes?.any { it.isDownloading }?:false
        if (sourceData.hasDownloads != hasDownloadTip) {
            sourceData.hasDownloads = hasDownloadTip
            downloadSourceAdapter.notifyItemChanged(sourceIndex)
        }
    }


    // 解析地址
    private fun parseVideoUrl(position: Int, success: (url: String, headerMap: Map<String, String>?) -> Unit) {
        val episode = downloadSource?.episodes?.getOrNull(position) ?: return
        val sourceId = downloadSource?.id ?: 0
        val videoUrl = episode.url
        val videoTitle = videoName
        val videoEpisodeTitle = episode.title
        // 下载专用的解析，可以同时解析多个
        AnalysisVideoTools.getVideoUrl(this, sourceId, videoUrl!!, videoTitle, videoEpisodeTitle, object : OnParseVideoListener {
            override fun onSuccess(sourceName: String?, url: String?, headerMap: Map<String, String>?) {
                LogC.e("parse -> ******* $url")
                if (url == null) {
                    return
                }
                success(url, headerMap)
            }

            override fun onFail(sourceName: String?) { // 此处反馈失败，说所有的解析以失败了
                // 自动切换线路
                val currentSourceId = downloadSource?.id ?: 0
                // 找到新的下载线路
                downloadSource = newPlayInfoList.firstOrNull { it.id < currentSourceId } ?: return
                // 继续尝试解析地址
                parseVideoUrl(position, success)
            }
        })
    }

    private fun execDownload(position: Int){
        val item = downloadAdapter.getItem(position)
        if (item.isDownloading) {
            AlertUtils.alert("当前视频已经在下载中...")
            return
        }

        if (freeStoreSize < 500 * 1024 * 1024) {// 不足500M，不让继续下载了
            // 不允许流量下载
            showErrorDialog("当前设备剩余可用存储空间不足，请先清理磁盘空间再进行下载！", getString(R.string.confirm), yesClickListener = {
                hideErrorDialog()
            })
            return
        }

        if (layoutLoading.visibility == View.VISIBLE) {
            AlertUtils.alert("正在获取下载地址，请耐心等待！")
            return
        }

        // 先解析
        // 显示加载状态，只有真正的解析需要
        val startShowTime = System.currentTimeMillis()
        layoutLoading.visibility = View.VISIBLE
        item.isDownloading = true
        item.status = Status.PENDING
        downloadAdapter.notifyItemChanged(position)

        // 先解析
        parseVideoUrl(position) { url, _ -> // 播放地址和对应的header集合
            val time = 500 - (System.currentTimeMillis() - startShowTime)
            if (time <= 0) {
                layoutLoading.visibility = View.GONE
            } else {
                RxUtils.delay(time) {
                    layoutLoading.visibility = View.GONE
                }
            }
//            Log.d(MultiDownloadManager.TAG, "execDownload -> ==========解析完成，url:$url==========")
            if (TextUtils.isEmpty(url)) {
                showErrorDialog("视频下载失败，请尝试切换其他线路进行下载！", "确认", yesClickListener = {
                    hideErrorDialog()
                })
                item.isDownloading = false
                item.status = Status.IDLE
                downloadAdapter.notifyItemChanged(position)
                return@parseVideoUrl
            }

            WBDownloadUtils.canAddTask(url) { canAddTask, errMsg ->
                if (!canAddTask) {
                    item.isDownloading = false
                    item.status = Status.IDLE
                    downloadAdapter.notifyItemChanged(position)
                    showErrorDialog(errMsg?:"当前任务无法正常添加！", "确认", yesClickListener = {
                        hideErrorDialog()
                    })
                    return@canAddTask
                }
                // 3.构建下载任务
                val downloadEntity = DownloadEntity(url, videoName)
                downloadEntity.coverUrl = videoPic
                // 新建下载任务
                downloadEntity.videoId = videoId
                downloadEntity.sourceId = downloadSource?.id ?: 0
                downloadEntity.episode = position
                downloadEntity.episodeName = item.title?:(position + 1).toString()
                downloadEntity.category = category
                downloadEntity.category = category
                downloadEntity.downloadType = WBDownloadUtils.getCurrentDownloadType()
                WBDownloadUtils.startDownload(task = downloadEntity)

                setFreeStoreSize(300 * 1024 * 1024)
            }
        }
    }


    override fun onDestroy() {
        super.onDestroy()
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this)
        }
        videoDownloadAdDialog?.dismiss()
    }

}